package com.gmall.product.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gmall.common.result.PageInfo;
import com.gmall.common.result.Result;
import com.gmall.model.product.BaseTrademark;
import com.gmall.model.product.SpuImage;
import com.gmall.model.product.SpuInfo;
import com.gmall.model.product.SpuPoster;
import com.gmall.product.mapper.BaseTrademarkMapper;
import com.gmall.product.mapper.SpuImageMapper;
import com.gmall.product.mapper.SpuInfoMapper;
import com.gmall.product.mapper.SpuPosterMapper;
import com.gmall.product.service.cache.BaseTrademarkCacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class SpuInfoService {

    @Autowired
    SpuInfoMapper spuInfoMapper;

    @Autowired
    SpuImageMapper spuImageMapper;

    @Autowired
    SpuPosterMapper spuPosterMapper;

    @Autowired
    BaseTrademarkMapper baseTrademarkMapper;

    @Autowired
    BaseTrademarkCacheService trademarkCacheService;

    public Result<PageInfo<SpuInfo>> selectPage(Long category3Id, Integer pageNo, Integer pageSize) {

        Page<SpuInfo> page = new Page<>(pageNo, pageSize);
        QueryWrapper<SpuInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SpuInfo::getCategory3Id, category3Id);
        Page<SpuInfo> spuInfoPage = spuInfoMapper.selectPage(page, queryWrapper);

        long total = spuInfoPage.getTotal();
        List<SpuInfo> records = spuInfoPage.getRecords();

        records.forEach(spuInfo ->{
            //BaseTrademark baseTrademark = baseTrademarkMapper.selectById(spuInfo.getTmId());
            BaseTrademark baseTrademark = trademarkCacheService.getTrademarkById(spuInfo.getTmId());

            spuInfo.setTmName(baseTrademark.getTmName());
        });
        PageInfo<SpuInfo> pageInfo = new PageInfo<>();
        pageInfo.setTotal(total);
        pageInfo.setRecords(records);

        return Result.ok(pageInfo);
    }

    @Autowired
    PlatformTransactionManager transactionManager;
    /**
     * ACID
     *  原子性，一致性，隔离性，持久性
     *  原子性（Atomic）  要不成功，要不失败 undo_log
     *  一致性（Consistence）
     *  ‌隔离性（Isolation）
     *  ‌持久性（Durability）             redo_log
     *  1、什么情况下事务回滚？
     *    默认抛出RuntimeException及其子类异常，事务回滚
     *  2、可以自定义出现哪些异常回滚，出现哪些异常不回滚
     *
     *  加上@Transactional注解，声明式事务
     *  编程式事务
     * @param spuInfo
     * @return
     */
    @Transactional(
            rollbackFor = Exception.class,
            noRollbackFor = ArithmeticException.class,
            timeout = 3000
            )
   //@MyTransactional
    public Result<String> saveSpuInfo(SpuInfo spuInfo) {
        Date now = new Date();
        spuInfo.setCreateTime(now);
        spuInfo.setUpdateTime(now);
        spuInfoMapper.insert(spuInfo);

        Long spuId = spuInfo.getId();

        List<SpuImage> spuImageList = spuInfo.getSpuImageList();

        int i = 10 / 0;//ArithmeticException

        spuImageList.stream().forEach((spuImage) -> {
            spuImage.setSpuId(spuId);
            spuImage.setCreateTime(now);
            spuImage.setUpdateTime(now);

            spuImageMapper.insert(spuImage);
        });//Lambda

        List<SpuPoster> spuPostList = spuInfo.getSpuPosterList();

        spuPostList.stream().forEach((spuPoster) -> {
            spuPoster.setSpuId(spuId);
            spuPoster.setCreateTime(now);
            spuPoster.setUpdateTime(now);

            spuPosterMapper.insert(spuPoster);
        });//Lambda
        return Result.ok("保存SPU信息成功");
    }



    @Transactional
    public Result<String> remove(Long spuId) {
        spuImageMapper.delete(new QueryWrapper<SpuImage>().lambda().eq(SpuImage::getSpuId, spuId));
        spuPosterMapper.delete(new QueryWrapper<SpuPoster>().lambda().eq(SpuPoster::getSpuId, spuId));
        spuInfoMapper.deleteById(spuId);
        return Result.ok("删除SPU成功");
    }
}
